# -*- coding: utf-8 -*-

from common import orm
from common.account.model.account import BALANCE_TYPE
from common.account.db.account import get_user_name, get_user_id_by_username
from common.transaction.model import TRANSACTION_STATUS, TRANSACTION_TYPE
from common.system_recharge.model import SystemRechargeBatch, SystemRechargeDetail
from common.utils import tracker
from common.transaction.db import create_transaction
from common.utils.decorator import sql_wrapper
from common.utils import exceptions as err
from common.utils.db import list_object
from common.utils.currency import convert_yuan_to_fen, convert_fen_to_hao, convert_fen_to_yuan
from common.black_account.db import update_withdraw_black
from common.black_account.model import WITHDRAW_BLACK_STATUS
from sqlalchemy import func


def _create_system_batch(trans_id, operator, count, content):
    form = SystemRechargeBatch()
    form.trans_id = trans_id
    form.operator = operator
    form.count = count
    form.note = content
    form.save(auto_commit=False)
    orm.session.flush()
    return form.id


def _create_system_detail(trans_id, batch_id, user_name, user_id, amount, operator, content, enable_withdraw):
    detail = SystemRechargeDetail()
    detail.trans_id = trans_id
    detail.batch_id = batch_id
    detail.user_name = user_name
    detail.user_id = user_id
    detail.amount = amount
    detail.enable_withdraw = enable_withdraw
    detail.operator = operator
    detail.note = content
    detail.save(auto_commit=False)
    orm.session.flush()
    return detail.as_dict()


@sql_wrapper
def create_system_trans(trans_id, params, operator, note, admin_id, black_type=None, enable_withdraw=False):
    count = len(params)
    query = get_trans_id(trans_id)
    if not query:
        raise err.ParamError(u'订单重复')

    for param in params:
        user_id = param.get('user_id', None)
        user_name = param.get('user_name', '')
        amount = param.get('amount', 0)
        amount = convert_yuan_to_fen(amount)
        if not user_id and not user_name:
            raise err.ParamError(u'用户昵称与ID至少输入一个')
        if not amount:
            raise err.ParamError(u'上分金额不能为空')
        if user_id and user_name:
            name = get_user_name(user_id)
            if name != user_name:
                raise err.ParamError(u'用户昵称与ID指向不同用户')
        if user_id or user_name:
            if user_id:
                user_name = get_user_name(user_id)
                if not user_name:
                    raise err.ParamError(u'未找到相关用户')
            else:
                user_id = get_user_id_by_username(user_name)
                if not user_id:
                    raise err.ParamError(u'未找到相关用户')

    batch_id = _create_system_batch(trans_id, operator, count, note)
    for param in params:
        user_id = param.get('user_id', None)
        user_name = param.get('user_name', '')
        amount = param.get('amount', 0)
        if user_id or user_name:
            if user_id:
                user_name = get_user_name(user_id)
            else:
                user_id = get_user_id_by_username(user_name)
        amount = convert_yuan_to_fen(amount)
        _create_system_detail(trans_id, batch_id, user_name,
                              user_id, amount, operator, note, enable_withdraw)
        data = {
            'user_id': user_id,
            'type': TRANSACTION_TYPE.SYSTEM_RECHARGE,
            'title': u'系统充值',
            'price': convert_fen_to_hao(amount),
            'status': TRANSACTION_STATUS.DONE
        }
        if enable_withdraw:
            data['balance_type'] = BALANCE_TYPE.WITHDRAW
        else:
            data['balance_type'] = BALANCE_TYPE.BALANCE

        create_transaction(data)
        tracker.track_system_recharge(int(user_id), convert_fen_to_yuan(amount))
        if black_type:
            info = {'type_account': user_id, 'type': black_type,
                    'note': u'上分拉黑', 'money': '0', 'reason': ''}
            update_withdraw_black(info, admin_id, WITHDRAW_BLACK_STATUS.ENABLE)
    orm.session.commit()


@sql_wrapper
def get_system_recharge_batch(limit=0, offset=0):
    query = SystemRechargeBatch.query.order_by(SystemRechargeBatch.created_at.desc())
    if limit > 0:
        query = query.limit(limit)
    if offset > 0:
        query = query.offset(offset)
    return query.all()


@sql_wrapper
def get_system_recharge_detail(batch_id):
    query = SystemRechargeDetail.query.filter(
        SystemRechargeDetail.batch_id == batch_id).order_by(
        SystemRechargeDetail.created_at.desc())
    return query.all()


@sql_wrapper
def get_system_recharge_detail_total(user_id):
    query = SystemRechargeDetail.query.filter(
        SystemRechargeDetail.user_id == user_id)
    total_amount = 0
    if query:
        total_amount = query.with_entities(func.sum(SystemRechargeDetail.amount)).scalar() or 0
    return total_amount


@sql_wrapper
def list_all_batch(query_dct):
    return list_object(query_dct, SystemRechargeBatch)


@sql_wrapper
def list_all_detail(query_dct):
    return list_object(query_dct, SystemRechargeDetail)


@sql_wrapper
def get_trans_id(trans_id):
    query = SystemRechargeBatch.query.with_for_update().filter(
            SystemRechargeBatch.trans_id == trans_id).first()
    if query:
        return False
    return True

